home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / LISP Related / U. Mass AI & LISP Tools / MODULES / DNET / DNET-Doc.text < prev    next >
Encoding:
Text File  |  1990-06-22  |  18.4 KB  |  427 lines  |  [TEXT/CCL ]

  1. ===========================================================================
  2.                         About DNET -- Dan Suthers
  3. ===========================================================================
  4. ;                          USER'S DOCUMENTATION
  5. ;
  6. ;  A discrimination net facility lets one do several things:
  7. ;
  8. ;  - 'Uniquify' list expressions under EQ by allowing one to retrive a stored
  9. ;    expression using an EQUAL expression as the key.
  10. ;  - Associate properties with list expressions (using the above capability).
  11. ;  - Ask whether a particular expression has been stored in a data base.
  12. ;  - Retrieve expressions by pattern matching using variables in either the
  13. ;    retrieval key or in the stored expressions.
  14. ;  - Change contexts efficiently by changing the discrimination net in use.
  15. ;
  16. ;  A discrimination net may be used to implement a simple data base, or to
  17. ;  support more sophisticated systems for deductive retrieval, forward and
  18. ;  backward chaining of rules, and/or truth maintenance.  The present package
  19. ;  attempts to be simple, general, and efficient by providing the most basic
  20. ;  operations efficiently implemented without frills.
  21. ;
  22. ;  Most operations take the discrimination net as their last argument.  This
  23. ;  facilitates context switching.  Storage of dotted lists is not allowed, 
  24. ;  due to the indexing method used.  Pattern matching retrieval processes 
  25. ;  variables in either the query pattern (MATCH-PATTERN) or the network 
  26. ;  (MATCH-EXPRESSION), or both (MATCH). The general MATCH function is less 
  27. ;  efficient, and most applications only need to match in one direction.
  28. ;
  29. ;  When a new expression is added via INDEXPR, some applications will need 
  30. ;  to do special processing of the expression and/or its dnet-terminal.  If 
  31. ;  this were left to the application after the INDEXPR call returned, this 
  32. ;  processing could not be done on expressions loaded from a file saved by 
  33. ;  SAVE-DNET, since the latter writes calls to INDEXPR with no surrounding 
  34. ;  application-specific forms.  The solution is to have an INDEXPR-HOOK, 
  35. ;  which when non-nil is a lambda called on all newly indexed expressions 
  36. ;  and their dnet-terminals.  There is also a corresponding DELEXPR-HOOK.
  37. ;
  38. ; Discrimination Net Operations:  
  39. ;    MAKE-DNET makes new ones.
  40. ;    RESET-DNET resets to empty and modifies associated info.
  41. ;    DNET-INFO associates information with a dnet.
  42. ;    ALL-EXPRESSIONS returns all expressions in a dnet (slow).
  43. ;    MAP-DNET-TERMINALS maps a function across all dnet-terminals in a dnet.
  44. ;    DESTROY-DNET undefines and deallocates a dnet.
  45. ;    SAVE-DNET saves a dnet to a file (slow).
  46. ;  (Functions requiring retrieval of all expressions are slow because DNET is
  47. ;  optimized for balancing fast access to single expressions with space economy.)
  48. ; Expression-Based Operations:
  49. ;  These do not process variables (treat variables like any other atom).
  50. ;   INDEXPR puts an expression in a dnet.
  51. ;   GETEXPR retrieves an expression from a dnet.
  52. ;   DELEXPR deletes an expression from a dnet.
  53. ;   EXPR-INFO associates information with an expression in a dnet.
  54. ;
  55. ; Pattern-Based Operations:
  56. ;  A pattern is a symbolic expression which may contain variables.  
  57. ;  Variables are symbols in the package ?.  It is recommended that
  58. ;  one declare all variables before use with the (defvariable <sym>) form.
  59. ;  No symbol should ever be uninterned from ? by another program.
  60. ;   DEFVARIABLE defines a variable.
  61. ;   VARIABLE-P tests whether an object is a variable. 
  62. ;   PATTERN-P tests whether an object is an expression containing a variable.
  63. ;   VARIABLES-IN-PATTERN returns a list of variables in a pattern.
  64. ;   MATCH retrieves patterns (or expressions) matching a given pattern (expression).
  65. ;   MATCH-PATTERN retrieves expressions matching a given pattern.
  66. ;   MATCH-EXPRESSION retrieves patterns matching a given expression.
  67. ;   BIND-VARS does the variable binding (restricted unification) for one-way
  68. ;     match candidates, and is exported for its potential usefulness.
  69. ;   UNIFY does bidirectional variable binding (for MATCH), and is exported.
  70. ;   SUBSTITUTE-BINDINGS substitutes for variables in a pattern to give an
  71. ;     expression, given a binding list.
  72. ;
  73. ; NOTE ON BEHAVIOR -- The following behavior is CORRECT:
  74. ;
  75. ;   ? (dnet:make-dnet :test-dnet)
  76. ;   ? (dnet:indexpr '(a b c) :test-dnet)
  77. ;   ? (dnet:indexpr '(a ?:x c) :test-dnet)
  78. ;   ? (dnet:indexpr '(a ?:y c) :test-dnet)
  79. ;   ? (dnet:indexpr '(a (?:x y z) c) :test-dnet)
  80. ;
  81. ;   ? (dnet:match-pattern '(a ?:x c) :test-dnet)
  82. ;   ((A (?:X Y Z) C) (A ?:Y C)     (A ?:X C)     (A B C))
  83. ;   (((?:X ?:X Y Z)) ((?:X . ?:Y)) ((?:X . ?:X)) ((?:X . B)))
  84. ;
  85. ;   ? (dnet:match-expression '(a ?:x c) :test-dnet)
  86. ;   ((A ?:X C)     (A ?:Y C))
  87. ;   (((?:X . ?:X)) ((?:Y . ?:X)))
  88. ;
  89. ;   ? (dnet:match '(a ?:x c) :test-dnet)
  90. ;   ((A ?:Y C)    (A ?:X C) (A B C))
  91. ;   (((?:X . ?:Y)) NIL      ((?:X . B)))
  92. ;   (NIL           NIL      NIL)
  93. ;
  94. ; MATCH-PATTERN ignores variables in the DNET.  Thus, (?:X Y Z) is a
  95. ;   constant list as far as it is concerned, and there is no contradiction
  96. ;   to binding ?:X to (?:X Y Z).  This feature may be useful when trying
  97. ;   to retrieve patterns without processing their variables.
  98. ; MATCH-EXPRESSION treats the ?:x in the query as a constant, so only
  99. ;   returns the patterns in the DNET which match it.  One happens to have
  100. ;   a variable which is the same as the constant; the other matches the
  101. ;   variable ?:y in DNET to the constant ?:x.
  102. ; MATCH will only return patterns which logically unify with the query
  103. ;   pattern.  Thus, it is correctly more restrictive than MATCH-PATTERN
  104. ;   above, as ?:X cannot be bound to an expression containing itself.
  105. ;   While MATCH returns bindings in both directions (the second and third
  106. ;   values), (?:Y . ?:X) does not appear in the second binding list for
  107. ;   (A ?:Y C) because (?:X . ?:Y) already expressed the binding, "using 
  108. ;   up" ?:Y.  I.e., there is no redundancy across the binding lists.
  109.  
  110. ---------------------------------------------------------------------------
  111.   Documentation for Exported Symbols in Package DNET (generated by PDOC):
  112. ---------------------------------------------------------------------------
  113.  
  114. *?-PACKAGE* Exported but undocumented Variable.
  115.  
  116. *DNET-PACKAGE* Exported but undocumented Variable.
  117.  
  118. ALL-EXPRESSIONS
  119.  Function:
  120.   all-expressions <dnet>                                           [Function]
  121.   Returns a list of all expressions in the indicated <dnet>.  The outer
  122.   list is constructed fresh and may be hacked.  This is time consuming.
  123.  
  124. BIND-VARS
  125.  Function:
  126.   bind-vars <pattern> <expression> <bindings>                      [Function]
  127.   Variables are processed in <pattern> but treated as atoms in <expression>.
  128.   <Bindings> should be existing bindings (usually nil). Dotted endings in 
  129.   <pattern> are assumed to be variables, and are processed. Returns two 
  130.   values: T or NIL to flag whether the pattern matches the expression, and 
  131.   a list of bindings which achieve this matching.
  132.  
  133. BROWSE-DNETS
  134.  Function:
  135.   browse-dnets &optional <build-mode>                              [Function]
  136.   Puts up a discrimination net browser.  If <build-mode> is nil (default), 
  137.   the default button is for pattern retrieval; if T, the default is for
  138.   adding an expression.
  139.  
  140. DEFVARIABLE
  141.  Function:
  142.   defvariable <sym>                                                   [Macro]
  143.   Interns the name of <sym> in the variable package ?, and exports it.  Use
  144.   to ensure the variable exists before using it in a pattern.  For example,
  145.   (defvariable x) lets us use ?:x as a variable in patterns.
  146.  
  147. DELEXPR
  148.  Function:
  149.   delexpr <expr> <dnet>                                            [Function]
  150.   Deletes the expression <expr> from <dnet>, calling DELEXPR-HOOK if it
  151.   is defined for the DNET.  Returns a DNET-TERMINAL iff it was deleted.
  152.  
  153. DESTROY-DNET
  154.  Function:
  155.   destroy-dnet <dnet>                                              [Function]
  156.   Destroys and undefines the entire <dnet>.
  157.  
  158. DNET
  159.  Function:
  160.   DNET name &key :indexpr-hook :delexpr-hook :info-place) [Macro]
  161.   Expands into CREATE-DNET call.  The first argument
  162.   is the name of the instance, and the remainder are optional keyword
  163.   arguments for uncomputed slot values, using defaults if not given.
  164.  
  165. DNET-COMPILED-DELEXPR-HOOK Exported but undocumented Function.
  166.  
  167. DNET-COMPILED-INDEXPR-HOOK Exported but undocumented Function.
  168.  
  169. DNET-DELEXPR-HOOK Exported but undocumented Function.
  170.  
  171. DNET-INDEXPR-HOOK Exported but undocumented Function.
  172.  
  173. DNET-INFO
  174.  Function:
  175.   dnet-info <dnet>                                                    [Macro]
  176.   Setf-able access to the information associated with <dnet>.
  177.  
  178. DNET-INFO-PLACE Exported but undocumented Function.
  179.  
  180. DNET-TERMINAL-EXPR Exported but undocumented Function.
  181.  
  182. DNET-TERMINAL-INFO Exported but undocumented Function.
  183.  
  184. EXPR-INFO
  185.  Function:
  186.   expr-info <expr> <dnet>                                          [Function]
  187.   Setf-able access to the information associated with <expr> in <dnet>.
  188.  
  189. GETEXPR
  190.  Function:
  191.   getexpr <expr> <dnet>                                            [Function]
  192.   Use to query whether <expr> has been stored in <dnet>, and to obtain the
  193.   name of its dnet-terminal.  Returns two values: the expression originally
  194.   stored in <dnet> (and is EQUAL to <expr>), and the dnet-terminal structure.
  195.   Both values are Nil if <expr> is not found. Variables are not processed.
  196.  
  197. INDEXPR
  198.  Function:
  199.   indexpr <expr> <dnet> &optional <info>                           [Function]
  200.   Ensures that <expr> is stored in <dnet>.  If the <expr> was not already
  201.   in <dnet>, initializes the associated information to <info> (if it was 
  202.   provided), and calls compiled-new-expr-hook (if non-nil) on <expr> and 
  203.   its dnet-terminal.  The latter allows application-specific processing of 
  204.   new expressions. Returns two values: the first is a predicate, T iff <expr> 
  205.   was newly added by this call; and the second is the dnet-terminal structure.
  206.  
  207. MAKE-DNET
  208.  Function:
  209.   make-dnet <name> &key <indexpr-hook> <delexpr-hook> <info>       [Function]
  210.    Returns a new (empty) discrimination net.  A name is generated unless
  211.    a symbol <name> is provided.  <Indexpr-hook> and <delexpr-hook> are
  212.    assumed to be lambda forms of two arguments which may be compiled.
  213.    These functions are applied to an expression and its corresponding 
  214.    DNET-TERMINAL the first time it is indexed into or deleted from the 
  215.    DNET, respectively. If the optional <info> is provided, the DNET's 
  216.    associated information is initialized to this value.
  217.  
  218. MAP-DNET-TERMINALS
  219.  Function:
  220.   map-dnet-terminals <f> <dnet>                                     [Function]
  221.   Maps <f> across dnet-terminals in the indicated <dnet>.  Returns NIL.
  222.  
  223. MATCH
  224.  Function:
  225.   match <pattern> <dnet>                                           [Function]
  226.   For retrieving all patterns unifying with a pattern: variables in both
  227.   are processed.  Returns three values: a list of all patterns in <dnet>
  228.   unifying with the <pattern>, a list of bindings of variables in <pattern>
  229.   to those in the matched patterns, and a list of bindings of variables in
  230.   the matched patterns to those in <pattern>.  The latter two values are
  231.   lists of lists containing pairs (<var> . <exp>), each representing the
  232.   binding of <var> to <exp> (ditto).  Note this is less efficient than
  233.   MATCH-PATTERN and MATCH-EXPRESSION, and should only be used when needed.
  234.   See also documentation for UNIFY.
  235.  
  236. MATCH-EXPRESSION
  237.  Function:
  238.   match-expression <expression> <dnet>                             [Function]
  239.   For retrieving all patterns (which may contain variables) matching an
  240.   expression.  Returns two values: a list of all patterns in <dnet> 
  241.   matching the <expression>, and a list of respective unifications.  The
  242.   latter is a list of lists containing pairs (<exp-part> . <pat-var>) 
  243.   representing the binding of <pat-var> to <exp-part>, a component of 
  244.   <expression>. Variables in <expression> are treated as constants.
  245.  
  246. MATCH-PATTERN
  247.  Function:
  248.   match-pattern <pattern> <dnet>                                   [Function]
  249.   For retrieving all expressions matching a pattern which may contain
  250.   variables.  Returns two values: a list of all expressions in <dnet>
  251.   matching the <pattern>, and a list of respective unifications.  The
  252.   latter is a list of lists containing pairs (<pat-var> . <dnet-exp>)
  253.   representing the binding of <pat-var> to <dnet-exp>, a component of
  254.   the corresponding returned expression.  Variables in the dnet are 
  255.   treated as constants.  A special facility provided only by this
  256.   function is dotted variables: any sublist of <pattern> may end in 
  257.   a dot followed by a variable.  This is like &rest binding.
  258.  
  259. NOT-A-DOTTED-LIST
  260.  Function:
  261.   not-a-dotted-list <expr>                                        [Function]
  262.   Returns T iff there is no non-nil atomic CDR in <expr>.
  263.  
  264. PATTERN-P
  265.  Function:
  266.   pattern-p <expr>                                                 [Function]
  267.   Returns non-NIL value iff <expr> is or contains a variable.
  268.  
  269. RESET-DNET
  270.  Function:
  271.   reset-dnet <dnet> &key <indexpr-hook> <delexpr-hook> <info>      [Function]
  272.   Empties an existing discrimination net.  Also enables one to modify
  273.   the hooks and associated info.  See MAKE-DNET.
  274.  
  275. SAVE-DNET
  276.  Function:
  277.   save-dnet <dnet> <path> &optional (write-in-package :dnet)       [Function]
  278.    Saves expressions required to recreate <dnet> to a file at <path>.
  279.    Returns the <path>.  The file is written in package <write-in-package>,
  280.    or DNET if the optional argument is unspecified. All associated info
  281.    is also saved.   Give <vars> a list of known variables.  This function 
  282.    is slow.
  283.  
  284. SUBSTITUTE-BINDINGS
  285.  Function:
  286.   substitute-bindings <bindings> <pattern>                         [Function]
  287.   Given <bindings> is an association list as returned by one of the match
  288.   functions, creates an expression from <pattern> where all the variables
  289.   have been replaced by their bindings.  New list structure is used.
  290.   Only makes one pass -- see substitute-transitive-bindings if variables
  291.   may be bound to each other.
  292.  
  293. SUBSTITUTE-TRANSITIVE-BINDINGS
  294.  Function:
  295.   substitute-bindings <bindings> <pattern>                         [Function]
  296.   Given <bindings> is an association list as returned by one of the match
  297.   functions, creates an expression from <pattern> where all the variables
  298.   have been replaced by their bindings.  New list structure is used.  
  299.   Makes as many passes are needed to eliminate transitivities which may
  300.   be returned by UNIFY when both patterns have variables, such as 
  301.   ((?:y . 3) (?:x . ?:y)) which unifies (?:x ?:x) and (?:y 3).
  302.  
  303. UNIFY
  304.  Function:
  305.   unify <pattern-1> <pattern-2> &optional <bindings-1> <bindings-2> [Function]
  306.   Given two list/atom patterns (each of which may contain variables), and
  307.   a (usually nil) set of initial bindings, returns three values: 
  308.     1. T or NIL to flag whether the patterns unify;
  309.     2. Bindings of variables in <pattern-1> to elements of <pattern-2>;
  310.     3. Bindings of variables in <pattern-2> to elements of <pattern-1>.
  311.   (The flag is returned first so UNIFY can be used as a predicate.  Since 
  312.   unification can succeed with no bindings, the other values will not serve 
  313.   this function.)  Example:
  314.     (unify '(a ?:x c) '(a (b) ?:y)) ==> T; ((?:X B)); ((?:Y . C))
  315.   Transitivity of bindings is not used for simplification, e.g. you could
  316.   get back T; ((?:X . ?:Y)); ((?:Y . C)). Modified from version by Ken Forbus.
  317.   This function is logically general, and hence checks for a variety of 
  318.   conditions.  It may be inefficient for specialized tasks: I recommend 
  319.   writing a specialized version if any assumptions may be made about the
  320.   patterns to be unified.
  321.  
  322. VARIABLE-P
  323.  Function:
  324.   variable-p <thing>                                                  [Macro]
  325.   Returns T iff <thing> is a variable (symbol in the ? package).
  326.  
  327. VARIABLES-IN-PATTERN
  328.  Function:
  329.   variables-in-pattern <pattern>                                   [Function]
  330.   Returns a list of variables occuring in <pattern>.
  331.  
  332. ---------------------------------------------------------------------------
  333.                                EXAMPLE
  334. ---------------------------------------------------------------------------
  335.  
  336. ;;; Making a DNET called TEST.
  337.  
  338. (dnet:make-dnet 'test)
  339. TEST
  340.  
  341. ;;; Adding expressions to the DNET.  INDEXPR returns two values: the first
  342. ;;; is T only if the expression is new to the DNET, and the second is the
  343. ;;; DNET-TERMINAL structure in which the expression is stored (this is 
  344. ;;; returned for code which needs to efficiently access the terminal).
  345.  
  346. (dnet:indexpr '(a b c) 'test)
  347. T
  348. #((A B C) NIL)
  349.  
  350. (dnet:indexpr '(junk this one) 'test)
  351. T
  352. #((JUNK THIS ONE) NIL)
  353.  
  354. ;;; Deletion is done by DELEXPR, which returns the DNET-TERMINAL object
  355. ;;; of the deleted expression (advanced code may need to operate on it),
  356. ;;; or NIL if the expression was not found to delete.
  357.  
  358. (dnet:delexpr '(junk this one) 'test)
  359. #((JUNK THIS ONE) NIL)
  360.  
  361. ;;; Let's add a few more expressions.
  362.  
  363. (dnet:indexpr '(a (b) c) 'test)
  364. T
  365. #((A (B) C) NIL)
  366.  
  367. (dnet:indexpr '(nil) 'test)
  368. T
  369. #((NIL) NIL)
  370.  
  371. ;;; We find out if an expression is in the DNET by using GETEXPR.  It returns
  372. ;;; two values.  The first is the expression if found, or NIL if it is not
  373. ;;; found.  The second value is the DNET-TERMINAL structure in which the
  374. ;;; expression is stored, provided for advanced code which needs efficient
  375. ;;; access to it:
  376.  
  377. (dnet:getexpr '(a b c) 'test)
  378. (A B C)
  379. #((A B C) NIL)
  380.  
  381. (dnet:getexpr '(junk this one) 'test)
  382. NIL
  383. NIL
  384.  
  385. ;;; Variables are represented as atoms interned in the ? package.  Before
  386. ;;; using a variable, we need to make sure it exists, as follows:
  387.  
  388. (dnet:defvariable x)
  389. T
  390.  
  391. ;;; Now we can see what things in the DNET match a given pattern:
  392.  
  393. (dnet:match-pattern '(a ?:x c) 'test)
  394. ((A B C) (A (B) C))                      ; two things match
  395. (((?:X . B)) ((?:X B)))
  396.  
  397. ;;; MATCH-PATTERN returns two values: a list of all expressions which match
  398. ;;; the given pattern, and a list of the bindings which makes the match 
  399. ;;; succeed.  Both of these are NIL if there is no match.
  400.  
  401. (dnet:match-pattern '(not there) 'test)
  402. NIL
  403. NIL
  404.  
  405. ;;; We can also store patterns in the DNET, and match expressions to the
  406. ;;; DNET to find out what patterns in the DNET match the given expression.
  407. ;;; The returned values are similar:
  408.  
  409. (dnet:defvariable y)
  410. T
  411.  
  412. (dnet:indexpr '(a ?:x ?:y) 'test)
  413. T
  414. #((A ?:X ?:Y) NIL)
  415.  
  416. (dnet:match-expression '(a b c) 'test)
  417. ((A B C) (A ?:X ?:Y))                    ; again, two things match
  418. (NIL ((?:Y . C) (?:X . B)))
  419.  
  420. ;;; See DNET-TEST and DNET-RULES for examples of other features of DNET.
  421. ;;; The file DNET-ANALYZE has a function which will report on the average
  422. ;;; and maximum depth and branching factor of a DNET, to help deal with
  423. ;;; efficiency problems.
  424. ===========================================================================
  425.